package com.yeskery.nut.util.http;

import javax.net.ssl.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

/**
 * Https 工具类
 * @author sprout
 * 2022-05-19 18:19
 */
public class HttpsClient extends HttpClient {

    /** 证书信任管理器数组 */
    private TrustManager[] trustManagers;

    /** 证书管理器数组 */
    private KeyManager[] keyManagers;

    /**
     * 构建Https工具类
     * @param trustManagerFactory 证书信任管理器工厂
     * @param keyManagerFactory 证书管理器工厂
     */
    public HttpsClient(TrustManagerFactory trustManagerFactory, KeyManagerFactory keyManagerFactory) {
        if (trustManagerFactory != null) {
            this.trustManagers = trustManagerFactory.getTrustManagers();
        }
        if (keyManagerFactory != null) {
            this.keyManagers = keyManagerFactory.getKeyManagers();
        }
    }

    /**
     * 构建Https工具类
     * @param trustManagerFactory 证书信任管理器工厂
     */
    public HttpsClient(TrustManagerFactory trustManagerFactory) {
        this(trustManagerFactory, null);
    }

    /**
     * 构建Https工具类
     * @param keyManagerFactory 证书管理器工厂
     */
    public HttpsClient(KeyManagerFactory keyManagerFactory) {
        this(null, keyManagerFactory);
    }

    /**
     * 构建Https工具类
     */
    public HttpsClient() {
    }

    /** 信任所有凭证 */
    private static final TrustManager[] TRUST_ALL_CERTS = new TrustManager[]{new X509TrustManager() {

        @Override
        public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {

        }

        @Override
        public void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {

        }

        @Override
        public java.security.cert.X509Certificate[] getAcceptedIssuers() {
            return new java.security.cert.X509Certificate[]{};
        }
    }};

    @Override
    protected HttpURLConnection createHttpUrlConnection(String httpUrl) throws Exception {
        SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
        sslContext.init(keyManagers, trustManagers == null ? TRUST_ALL_CERTS : trustManagers, new java.security.SecureRandom());
        SSLSocketFactory ssf = sslContext.getSocketFactory();
        URL url = new URL(httpUrl);
        HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
        connection.setSSLSocketFactory(ssf);
        return connection;
    }
}
